use std::sync::Arc;

use axum::{
    async_trait,
    extract::{FromRequest, RequestParts}, http::HeaderMap,
};

use crate::{error::AppError, model::AppState, app, config::Config, session, handler::helper::session_cached};

///
/// 授权校验
/// 
pub struct Authed {}

#[async_trait]
impl<B> FromRequest<B> for Authed
where
    B: Send,
{
    type Rejection = AppError;

    async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
        let headers = req.headers();
        tracing::debug!("authed {:?}...", headers);
        let admin_session = is_authed(headers);
        if let Some(session_val) = admin_session {
            tracing::debug!("authed session is: {}", session_val);
            return Ok(Self {});
        }
        Err(AppError::auth_error("UNAUTHENTICATED"))
    }
}

fn is_authed(headers: &HeaderMap,)->Option<String>{
    let authorization= headers.get("Authorization");
    match authorization {
        Some(val) => {
            let cfg = &app::get_config::<Config>().session;
            let cached_key = format!("{}{}", &cfg.prefix, val.to_str().unwrap().replace("Bearer ", ""));
            
            tracing::debug!("{}", &cached_key);
        
            session_cached(cached_key, None)
        },
        None => None,
    }
}
